import * as fs from "fs";
import * as yaml from "js-yaml";
import { HelmRepo, HelmRepoManager } from "./helm-repo-manager"
import logger from "./logger";
import { promiseExec } from "./promise-exec"
import { helmCli } from "./helm-cli"

type CachedYaml = {
  entries: any;
}

export class HelmChartManager {
  protected cache: any
  protected repo: HelmRepo
  constructor(repo: HelmRepo){
    this.cache = HelmRepoManager.cache
    this.repo = repo
  }

  public async chart(name: string) {
    const charts = await this.charts()
    return charts[name]
  }

  public async charts(): Promise<any> {
    try {
      const cachedYaml = await this.cachedYaml()
      return cachedYaml["entries"]
    } catch(error) {
      logger.error(error)
      return []
    }
  }

  public async getReadme(name: string, version = "") {
    const helm = await helmCli.binaryPath()
    if(version && version != "") {
      const { stdout, stderr} = await promiseExec(`"${helm}" show readme ${this.repo.name}/${name} --version ${version}`).catch((error) => { throw(error.stderr)})
      return stdout
    } else {
      const { stdout, stderr} = await promiseExec(`"${helm}" show readme ${this.repo.name}/${name}`).catch((error) => { throw(error.stderr)})
      return stdout
    }
  }

  public async getValues(name: string, version = "") {
    const helm = await helmCli.binaryPath()
    if(version && version != "") {
      const { stdout, stderr} = await promiseExec(`"${helm}" show values ${this.repo.name}/${name} --version ${version}`).catch((error) => { throw(error.stderr)})

      return stdout
    } else {
      const { stdout, stderr} = await promiseExec(`"${helm}" show values ${this.repo.name}/${name}`).catch((error) => { throw(error.stderr)})

      return stdout
    }
  }

  protected async cachedYaml(): Promise<CachedYaml> {
    if (!(this.repo.name in this.cache)) {
      const cacheFile = await fs.promises.readFile(this.repo.cacheFilePath, 'utf-8')
      const data = yaml.safeLoad(cacheFile)
      for(const key in data["entries"]) {
        data["entries"][key].forEach((version: any) => {
          version['repo'] = this.repo.name
          version['created'] = Date.parse(version.created).toString()
        })
      }
      this.cache[this.repo.name] = Buffer.from(JSON.stringify(data))
    }
    return JSON.parse(this.cache[this.repo.name].toString())
  }
}
